package cn.tanghom.app.system.controller;

import java.util.Date;

import cn.tanghom.app.system.mapper.UserMapper;
import cn.tanghom.app.system.model.User;
import cn.tanghom.app.system.service.UserService;
import cn.tanghom.conf.CommonKey;
import cn.tanghom.support.utils.Md5Util;
import cn.tanghom.support.utils.RedisUtil;
import cn.tanghom.support.utils.StringUtils;
import cn.tanghom.support.utils.Validator;
import cn.tanghom.support.utils.YunPianSms;
import cn.tanghom.support.web.BaseController;
import cn.tanghom.support.web.Device;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.util.SavedRequest;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.support.RequestContext;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import static cn.tanghom.support.web.BaseController.*;

/**
 * 登录登出
 *
 * @author tanghom
 */
@Controller
@RequestMapping
public class LoginController {
	String login = THEME_PATH + "/login";
	 
	private static final String authOperator = "authOperator";
	    
    private static final String forgetPwByPhone = "forgetpasswordbyphone";
    
    private static final String register = "register";
    
    private static final boolean CheckVerifCode = false;
	 
	 @Resource
	 private UserService userService;
	 
	 @Resource
	 private UserMapper userMapper;
	 
    /**
     * 登录入口
     * @param request
     * @return
     */
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String login(HttpServletRequest request) {
    	String url = request.getParameter(redirectUrl);
    	if(url!=null){
    		request.setAttribute(redirectUrl,url);
    	}
    	Device device = BaseController.getDevice();
    	if(device.isMobile()){
    		//使用手机号码登录
    		login = THEME_PATH + "/system/user/login_mobile";
    	}
    	else{ 
    		//不切换登录页面。
    		//login = THEME_PATH + "/login";
    	}
    	//Subject user = SecurityUtils.getSubject();
        request.removeAttribute("error");
        return login;//pc platform
    }

    /**
     * 登录
     * @param loginName  登录名
     * @param loginPwd 密码
     * @param request
     * @return
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String doLogin(String loginName, String loginPwd, HttpServletRequest request) {
        try {
            if(StringUtils.isNullOrEmpty(loginName)|| StringUtils.isNullOrEmpty(loginPwd)){
                request.setAttribute("error","请输入用户名和密码");
                return login;
            }
            Subject user = SecurityUtils.getSubject();
            String loginPwdMd5 = Md5Util.encrypt(loginPwd);
            UsernamePasswordToken token = new UsernamePasswordToken(loginName, loginPwdMd5);
            try {
            	token.setRememberMe(true); 
                user.login(token);
            } catch (LockedAccountException lae) {
                token.clear();
                request.setAttribute("error", "用户已经被锁定不能登录，请与管理员联系！");
                return login;
            } catch (IncorrectCredentialsException e) {
                token.clear();
                request.setAttribute("error", "登录失败,密码错误!");
                return login;
            } catch (AuthenticationException e) {
                token.clear();
                request.setAttribute("error", "帐号或密码不正确！");
                return login;
            }
        }catch (Exception e){
            request.setAttribute("error","程序异常");
            return login;
        }
        //add@byron
        request.getSession().setAttribute("username", loginName);
       
        request.removeAttribute("error");
        
        String rurl = request.getParameter(redirectUrl);
    	if(rurl!=null){
    		return "redirect:"+rurl;
    	}
    	//end@
        SavedRequest  sreq = WebUtils.getSavedRequest(request);
        if(sreq!=null){
	        String url = sreq.getRequestUrl();
	        if(url!=null){
	        	return "redirect:"+url;
	        }
        }
        return "redirect:/";
    }
    
    @RequestMapping(value = "/logout")
    public String logout(HttpSession session) {  
    	Subject user = SecurityUtils.getSubject();
    	if(user!=null){
    		user.logout();
    	}
    	session.removeAttribute(CommonKey.USER_SESSION);  
    	session.removeAttribute("username");  
        return "redirect:/login";
    }
    
    @RequestMapping(value= "/user/register",method = RequestMethod.GET)
	public String register() {
		return THEME_PATH+"/system/user/register";
	}
    

	/**
	 * 忘记密码 页面
	 * @param model
	 * @param redirect
	 * @return
	 */
	@RequestMapping("/user/forgotpassword")
	public String forgotpassword(Model model,String redirect) {
		model.addAttribute("redirect", redirect);
		return THEME_PATH+"/system/user/forgotpasswordbyphone";
	}
	
    /**
	 * 忘记密码（及注册） 发送短信验证	
	 * @param jwttoken
	 * @return
	 */
	@RequestMapping(value = "user/sentphone", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
	@ResponseBody
	@ResponseStatus(value = HttpStatus.OK)
	public String sentphone(String phone, String redirect,String category){
	
	    try {
	    	if(phone.equals(null)||phone.equals("")){ return renderJson("status",CommonKey.ERROR,"message","手机号码不可为空"); }
	    	
	        User tUserDetail = userService.findByPhone(phone);
	        String key = String.valueOf((int)((Math.random()*9+1)*100000));
	        
	        //保存验证短信验证码到缓存，判断是注册还是忘记密码
	        if(category.equals(forgetPwByPhone)){
	        	if(tUserDetail == null){	        		
	        		return renderJson("status",CommonKey.ERROR,"message","手机号码不存在，请注册"); 
	        	}
		        RedisUtil.INSTANCE.saddByPw(forgetPwByPhone+"_"+phone, key);
	        }else if(category.equals(register)){
	        	if(tUserDetail != null){	        	
	        		return renderJson("status",CommonKey.ERROR,"message","手机号码已注册"); 
	        	}
		        RedisUtil.INSTANCE.saddByPw(register+"_"+phone, key);
	        }else{	   	
	        	if(tUserDetail == null){	        		
	        		return renderJson("status",CommonKey.ERROR,"message","手机号码不存在，请注册"); 
	        	}
		        RedisUtil.INSTANCE.saddByPw(authOperator+"_"+phone, key);
	        }
	        
	        //发送验证码
	        String code = YunPianSms.sendCode(phone,key);	        
	       
	        if (!code.equals("OK")) {
	        	
		        if(category.equals(forgetPwByPhone)){
			        RedisUtil.INSTANCE.srem(forgetPwByPhone+"_"+phone);
		        }else if(category.equals(register)){
			        RedisUtil.INSTANCE.srem(register+"_"+phone);
		        }
	        	
		        if (code.equals("isv.BUSINESS_LIMIT_CONTROL")) {		        	
		        	return renderJson("status",CommonKey.ERROR,"message","验证码发送失败，频繁发送"); 
		        }else{		        	
		        	return renderJson("status",CommonKey.ERROR,"message","验证码发送失败，返回code:"+code); 
		        }
			}	        
	     
	        return renderJson("status",CommonKey.SUCCESS,"message","验证码正在发送，请耐心等待"); 
	        
	    } catch (Exception e) {	      
	        return renderJson("status",CommonKey.ERROR,"message","验证码发送失败"); 
	    }	  
	}
	
	/**
	 * 忘记密码 修改密码页面
	 * @param model
	 * @param phone
	 * @param redirect
	 * @param key
	 * @return
	 */
	@RequestMapping("/user/newpassword")
	public String newpassword(Model model,String phone, String redirect,String key) {		
		model.addAttribute("phone", phone);
		model.addAttribute("redirect", redirect);
		model.addAttribute("key", key);
		if(CheckVerifCode){
	    	if(!RedisUtil.INSTANCE.sismember(forgetPwByPhone+"_"+phone)){
	    		model.addAttribute("message", "验证码已过期，重新发送");
	    		return THEME_PATH +"/system/user/forgotpasswordbyphone";
	    	}else if(!RedisUtil.INSTANCE.sget(forgetPwByPhone+"_"+phone).equals(key)){
	    		model.addAttribute("message", "验证码错误");
	    		return THEME_PATH +"/system/user/forgotpasswordbyphone";
	    	}
		}
    	return THEME_PATH +"/system/user/newpassword";
	}
    
    /**
     * 忘记密码 提交修改密码
     * @return
     */
    @RequestMapping(value = "/user/resetpw", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public String resetpw(String phone, String newpassword,String checknewpassword, String redirect,String key, Model model){
		model.addAttribute("phone", phone);
		model.addAttribute("redirect", redirect);
		model.addAttribute("key", key);
		if(CheckVerifCode){
	    	if(!RedisUtil.INSTANCE.sismember(forgetPwByPhone+"_"+phone)){
	    		model.addAttribute("message", "验证码已过期，重新发送");
	    		return THEME_PATH +"/system/user/forgotpasswordbyphone";
	    	}else if(!RedisUtil.INSTANCE.sget(forgetPwByPhone+"_"+phone).equals(key)){
	    		model.addAttribute("message", "验证码错误");
	    		return THEME_PATH +"/system/user/forgotpasswordbyphone";
	    	}
		}
    	
    	if(newpassword.equals(null)||newpassword.equals("")){model.addAttribute("message", "密码已不可为空");return THEME_PATH +"/system/user/newpassword";}
    	if(!Validator.isPassword(newpassword)){model.addAttribute("message", "密码格式不正确");return THEME_PATH +"/system/user/newpassword";}
    	if(!newpassword.equals(checknewpassword)){model.addAttribute("message", "两次密码输入不一致");return THEME_PATH +"/system/user/newpassword";}
    	
    	User tUserDetail = userService.findByPhone(phone);
    	tUserDetail.setLoginPwd(newpassword);
    	//tUserDetail.setLoginPwd(DigestUtils.md5DigestAsHex(newpassword.getBytes()));
    	userService.update(tUserDetail);
    	
    	RedisUtil.INSTANCE.srem(phone);
    	
    	return "redirect:/logout?redirect=" + redirect;
    }
    /**
     * 注册
     * @param httpServletRequest
     * @param httpServletResponse
     * @param email
     * @param phone
     * @param password
     * @param redirect
     * @param model
     * @return
     */
    @RequestMapping(value = "/user/register", method = RequestMethod.POST)
    public String register(String email,String phone, String password,String confirmPwdCipher, String redirect, String key,Model model
    		,String fullname,String company,String position,String wechat,String registerway){
    	System.out.println("注册  " + email +" "+phone+ " " + password+" "+confirmPwdCipher + " " + redirect + " " + fullname + " " + company + " " + position + " " + wechat + " " + registerway);
    	String registerPage = THEME_PATH +"/system/user/register";
		model.addAttribute("email", email);
		model.addAttribute("phone", phone);
		model.addAttribute("redirect", redirect);
		model.addAttribute("key", key);
		
		model.addAttribute("fullname", fullname);
		model.addAttribute("company", company);
		model.addAttribute("position", position);
		model.addAttribute("wechat", wechat);
		model.addAttribute("registerway", registerway);
    	
    	if(email.equals(null)||email.equals("")){ 
    		model.addAttribute("message", "邮箱不可为空");
    		return THEME_PATH +"/system/user/register";
    	}
    	if(checkMail(email)>0){
        	model.addAttribute("message", "邮箱已存在");
        	return THEME_PATH +"/system/user/register";
    	}
    	if(!Validator.isEmail(email)){model.addAttribute("message", "邮箱格式不正确");return registerPage;}
    	model.addAttribute("email", email);
    	
    	if(phone.equals(null)||phone.equals("")){model.addAttribute("message", "手机号不可为空");return registerPage;}
    	if(checkPhone(phone)>0){
        	model.addAttribute("message", "手机号已存在");
        	return registerPage;
    	}
    	if(!Validator.isMobile(phone)){model.addAttribute("message", "手机号格式不正确");return registerPage;}
    	model.addAttribute("phone", phone);
    	
    	if(fullname.equals(null)||fullname.equals("")){model.addAttribute("message", "姓名不可为空");return registerPage;}
    	if(company.equals(null)||company.equals("")){model.addAttribute("message", "工作单位不可为空");return registerPage;}
    	if(position.equals(null)||position.equals("")){model.addAttribute("message", "职位不可为空");return registerPage;}
    	//if(wechat.equals(null)||wechat.equals("")){model.addAttribute("message", "微信号不可为空");return registerPage;}
    	if(registerway.equals(null)||registerway.equals("")){model.addAttribute("message", "注册途径不可为空");return registerPage;}
    	
    	
    	if(key.equals(null)||key.equals("")){model.addAttribute("message", "验证码不可为空");return registerPage;}
    	
    	if(CheckVerifCode){
	    	if(!RedisUtil.INSTANCE.sismember(register+"_"+phone)){
	    		model.addAttribute("message", "注册验证码已过期，重新发送");
	    		return registerPage;
	    	}else if(!RedisUtil.INSTANCE.sget(register+"_"+phone).equals(key)){
	    		model.addAttribute("message", "注册验证码错误");
	    		return registerPage;
	    	}
    	}
    	
    	if(password.equals(null)||password.equals("")){model.addAttribute("message", "密码已不可为空");return registerPage;}
    	if(!Validator.isPassword(password)){model.addAttribute("message", "密码格式不正确");return registerPage;}
    	if(!password.equals(confirmPwdCipher)){model.addAttribute("message", "两次密码输入不一致");return registerPage;}

    	User tUserDetail = new User();
    	tUserDetail.setLoginName(phone);
    	tUserDetail.setEmail(email);
    	tUserDetail.setPhone(phone);
    	tUserDetail.setLoginPwd(password);
    	//-tUserDetail.setLoginPwd(DigestUtils.md5DigestAsHex(password.getBytes()));
    	tUserDetail.setCreateTime(new Date());
    	tUserDetail.setStatus(1);
    	
    	tUserDetail.setUserName(fullname);
    	tUserDetail.setOrganizationName(company);
    	//tUserDetail.setPosition(position);
    	//tUserDetail.setWechat(wechat);
    	//tUserDetail.setRegisterway(registerway);
    	
    	userService.save(tUserDetail);
    	model.addAttribute("message", "注册成功，账号需要审核请等待");
    	model.addAttribute("redirect", redirect);
    	return THEME_PATH +"/system/user/registersuccess";
    }
    
    /**
     * 验证邮箱是否有效
     * @param key
     * @return
     */
    @RequestMapping(value = "checkMail", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    @ResponseBody
    @ResponseStatus(value = HttpStatus.OK)
    public long checkMail(String key){    
    	return userMapper.countUserByEmail(key);
    }
    
    /**
     * 验证手机是否有效
     * @param key
     * @return
     */
    @RequestMapping(value = "checkPhone", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    @ResponseBody
    @ResponseStatus(value = HttpStatus.OK)
    public long checkPhone(String key){
    	return userMapper.countUserByPhone(key);
    }
}
